<?php

use think\Db;

if(!function_exists('listen')){
	/**
	 * 监听行为
	 *
	 * @param string $tag
	 */
	function listen($tag){
		app('hook')->listen($tag);
	}
}

if(!function_exists('weight')){
	/**
	 * 执行小挂件
	 *
	 * @param string $url
	 * @param array  $vars
	 * @param bool   $appendSuffix
	 * @return mixed
	 */
	function weight($url, $vars = [], $appendSuffix = false){
		return app()->action($url, $vars, 'weight', $appendSuffix);
	}
}

/**
 * 获取属性类型
 *
 * @param string $type
 * @return array|mixed|null
 */
function get_attribute_type($type = null){
	static $_type = [
		'number'   => ['数字', 'int(11) UNSIGNED NOT NULL'],
		'string'   => ['字符串', 'varchar(255) NOT NULL'],
		'textarea' => ['文本框', 'text NOT NULL'],
		'date'     => ['日期', 'int(10) UNSIGNED NOT NULL'],
		//		'time'     => ['时间', 'int(10) UNSIGNED NOT NULL'],
		'datetime' => ['日期时间', 'int(10) UNSIGNED NOT NULL'],
		'switch'   => ['布尔', 'tinyint(2) UNSIGNED NOT NULL'],
		'select'   => ['枚举', 'varchar(50) NOT NULL'],
		'radio'    => ['单选', 'varchar(12) NOT NULL'],
		'checkbox' => ['多选', 'varchar(128) NOT NULL'],
		'editor'   => ['编辑器', 'text NOT NULL'],
		'picture'  => ['上传图片', 'varchar(128) NOT NULL'],
		'file'     => ['上传附件', 'varchar(128) NOT NULL'],
	];
	if(is_null($type)) return $_type;

	return $type ? isset($_type[$type]) ? $_type[$type] : null : null;
}

/**
 * 范围日期转换时间戳
 *
 * @param string $range_datetime
 * @param int    $max_range 最大时间间隔
 * @param string $delimiter
 * @return array
 */
function parse_range_datetime($range_datetime, $max_range = 0, $delimiter = ' - '){
	$range_datetime = explode($delimiter, $range_datetime, 2);
	$range_datetime[0] = strtotime($range_datetime[0]);
	$range_datetime[1] = isset($range_datetime[1]) ? strtotime($range_datetime[1]) : time();

	// 如果结束时间小于或等于开始时间 直接返回null
	if($range_datetime[1] < $range_datetime[0]){
		return null;
	}

	// 如果大于最大时间间隔 则用结束时间减去最大时间间隔获得开始时间
	if($max_range > 0 && $range_datetime[1] - $range_datetime[0] > $max_range){
		$range_datetime[0] = $range_datetime[1] - $max_range;
	}

	return $range_datetime;
}

/**
 * 获取相对时间
 *
 * @param int $timeStamp
 * @return string
 */
function relative_date($timeStamp){
	$currentTime = time();

	// 判断传入时间戳是否早于当前时间戳
	$isEarly = $timeStamp <= $currentTime;

	// 获取两个时间戳差值
	$diff = $currentTime - $timeStamp;

	// 如果$isEarly为false则差值取反
	if(!$isEarly) $diff = -$diff;
	$dirStr = $isEarly ? '前' : '后';

	if($diff < 60000) $resStr = intval($diff / 1000).'秒'.$dirStr;
	// 多于59秒，少于等于59分钟59秒
	elseif($diff >= 60000 && $diff < 3600000) $resStr = floor($diff / 60000).'分钟'.$dirStr;
	// 多于59分钟59秒，少于等于23小时59分钟59秒
	elseif($diff >= 3600000 && $diff < 86400000) $resStr = floor($diff / 3600000).'小时'.$dirStr;
	// 多于23小时59分钟59秒，少于等于29天59分钟59秒
	elseif($diff >= 86400000 && $diff < 2623860000) $resStr = floor($diff / 86400000).'天'.$dirStr;
	// 多于29天59分钟59秒，少于364天23小时59分钟59秒，且传入的时间戳早于当前
	elseif($diff >= 2623860000 && $diff <= 31567860000 && $isEarly) $resStr = date('MM-dd hh:mm', $timeStamp);
	else $resStr = date('Y-m-d', $timeStamp);

	return $resStr;
}

/**
 * 生成计算位置字段
 *
 * @param float  $longitude
 * @param float  $latitude
 * @param string $lng_name
 * @param string $lat_name
 * @param string $as_name
 * @return string
 */
function build_mysql_distance_field($longitude, $latitude, $lng_name = 'longitude', $lat_name = 'latitude', $as_name = 'distance'){
	return "ROUND(6378.138*2*ASIN(SQRT(POW(SIN(({$latitude}*PI()/180-{$lat_name}*PI()/180)/2),2)+COS({$latitude}*PI()/180)*COS({$lat_name}*PI()/180)*POW(SIN(({$longitude}*PI()/180-{$lng_name}*PI()/180)/2),2)))*1000) AS {$as_name}";
}

/**
 * 获取数据库数据
 *
 * @param string $table
 * @param array  $where
 * @param string $field
 * @param string $order
 * @param string $page
 * @return array|string|\think\Collection
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
function table_rows($table, $where = [], $field = '*', $order = '', $page = ''){
	return Db::name($table)->field($field)->where($where)->order($order)->page($page)->select();
}

/**
 * 获取数据库数据
 *
 * @param string $table
 * @param string $field
 * @param array  $where
 * @param string $key
 * @param string $order
 * @param string $page
 * @return array
 */
function table_column($table, $field, $where = [], $key = '', $order = '', $page = ''){
	return Db::name($table)->where($where)->order($order)->page($page)->column($field, $key);
}

/**
 * 获取数据库值
 *
 * @param string       $table
 * @param string       $field 字段名
 * @param array|string $where
 * @param mixed        $default 默认值
 * @return mixed
 */
function table_value($table, $field, $where, $default = null){
	return Db::name($table)->where($where)->value($field, $default);
}

/**
 * 获取图片地址
 *
 * @param string $path
 * @return mixed
 */
function get_cover_path($path){
	if(strpos($path, '/') === 0){
		return request()->domain().$path;
	}
	return $path;
}

/**
 * 获取封面信息
 *
 * @param int    $pictureId
 * @param string $field
 * @return mixed
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
function get_cover($pictureId, $field = null){
	static $data = [];
	if(!isset($data[$pictureId])){
		$data[$pictureId] = Db::name('picture')->where('id', $pictureId)->find();
	}
	$info =& $data[$pictureId];
	return ($field && $info) ? $info[$field] : $info;
}

/**
 * 获取分类列表
 *
 * @return array|string|\think\Collection
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\DbException
 * @throws \think\db\exception\ModelNotFoundException
 */
function get_category_tree(){
	$data = table_rows('category', [], '*', 'sort asc');
	$data = \xin\helper\Arr::tree($data);
	return $data;
}

/**
 * 关键字分词
 *
 * @param string $keyword
 * @param int    $num 最大返回条数
 * @param int    $holdLength 保留字数
 * @return array
 */
function analysis_words($keyword, $num = 5, $holdLength = 48){
	if($keyword === null || $keyword === "") return [];
	if(mb_strlen($keyword) > $holdLength) $keyword = mb_substr($keyword, 0, 48);

	//执行分词
	$pa = new \xin\analysis\Analysis('utf-8', 'utf-8');
	$pa->setSource($keyword);
	$pa->startAnalysis();
	$result = $pa->getFinallyResult($num);
	if(empty($result)) return [$keyword];

	return array_unique($result);
}

/**
 * 编译查询关键字SQL
 *
 * @param string $keywords
 * @return array
 */
function build_keyword_sql($keywords){
	$keywords = analysis_words($keywords);
	return array_map(function($item){
		return "%{$item}%";
	}, $keywords);
}
